/*
	Copyright (c) 2007, ANYwebcam.com Pty Ltd. All rights reserved.

	The software in this package is published under the terms of the BSD style 
	license, a copy of which has been included with this distribution in the 
	license.txt file.
*/
package com.anywebcam.di.component
{
	import com.anywebcam.di.*;
	import com.anywebcam.di.error.*;
	import com.anywebcam.reflection.*;

	/**
	 * Instantiates an instance of the managed type and injects values into the setters 
	 * specified in this DIComponent's parameters array.
	 */
	public class SetterInjectionComponent extends InstantiatingComponent
	{
		/**
		 * @inheritDoc
		 */
		public function SetterInjectionComponent( key:Object, type:Class, parameters:Array=null )  
		{
			super( key, type, parameters );
		}
		
		/**
		 * @inheritDoc
		 */
		override public function getInstance( container:DIContainer ):Object
		{
			var instance:Object = new type();
			
			var component:DIComponent = this;
			
			// loop over each parameter
			if( parameters ) parameters.forEach( function( param:Object, index:int, array:Array ):void
			{
				var key:String;
				var value:Object;
				var setter:MethodInfo;
				
				if( param is String )
				{
					key = param as String;
					
					setter = classInfo.setter( param as String );
					if( !setter ) throw new UnsettableSetterError( component, key );

					//trace( component, instance, key, 'setter:', setter, setter.description.toXMLString() );

					value = getParameterValue( container, setter.parameters[0] );
				}
				else
				{
					for( var property:String in param )
					{
						key = property;
						
						setter = classInfo.setter( property );
						
						if( !setter ) throw new UnsettableSetterError( component, key );
						
						value = getParameterValue( container, param[ key ] );
						break;
					}
				}
				
				//trace( component, instance, key, value );
				
				setter.invoke( instance, value );
			});
			
			return instance;
		}		
	}
}